package com.uniovi.nmapgui.nmap.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.uniovi.nmapgui.model.Command;
import com.uniovi.nmapgui.model.Host;
import com.uniovi.nmapgui.nmap.entity.Commandnested;
import com.uniovi.nmapgui.nmap.entity.Task;
import com.uniovi.nmapgui.nmap.entity.TaskIp;
import com.uniovi.nmapgui.nmap.mapper.CommandnestedMapper;
import com.uniovi.nmapgui.nmap.service.ICommandnestedService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.uniovi.nmapgui.nmap.service.ITaskIpService;
import com.uniovi.nmapgui.nmap.service.ITaskService;
import com.uniovi.nmapgui.util.JsoupManger;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.joda.time.DateTime;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jobob
 * @since 2020-12-24
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class CommandnestedServiceImpl extends ServiceImpl<CommandnestedMapper, Commandnested> implements ICommandnestedService {

    @Resource
    CommandnestedMapper commandnestedMapper;
    @Autowired
    ITaskService iTaskServiceImlp;
    @Autowired
    ITaskIpService iTaskIpServiceImlp;
    @Value("${complexUrl}")
    String complexUrl;
    @Autowired
    ITaskService taskServiceImpl;

    @Transactional
    @Override
    public void saveToMysql(String text, Task task) {

        //更新
        QueryWrapper queryWrapper = new QueryWrapper(task);
        Task t = iTaskServiceImlp.getById(task.getId());
        if (t == null) {
            return;
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        t.setEndtime(simpleDateFormat.format(new Date()));
        iTaskServiceImlp.updateById(t);
        //解析xml数据 并保存至副表
        List<TaskIp> taskIps = JsoupManger.getMesFromText2(text, t.getTasknewid(), task.getSummary());
        //System.out.println(taskIps.size());
        for (int i = 0; i < taskIps.size(); i++) {
            iTaskIpServiceImlp.save(taskIps.get(i));
        }
        //在检测完资产之后将 信息返回至资产平台
        if (taskIps.size() > 0) {
            System.out.println("******************" + JSON.toJSONString(taskIps));
            Thread t1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        sendMsg(taskIps);
                    } catch (Exception e) {

                    }
                }
            });
            t1.start();
        }
    }


    @Override
    public void saveToMysqlNew(Command command, Task task) {
        if (command != null && command.getText() != null) {
            Commandnested commandnested = new Commandnested();
            commandnested.setOutput(JSON.toJSONString(command.getOutput()));
            QueryWrapper wrapper = new QueryWrapper<>(commandnested);
            Commandnested commandnestedOld = commandnestedMapper.selectOne(wrapper);
            if (commandnestedOld == null) {

                //当前数据库中并没有 此条检测结果  将结果保存
                Commandnested commandnestedNew = new Commandnested(command);
                commandnestedMapper.insert(commandnestedNew);
                QueryWrapper queryWrapper = new QueryWrapper(task);
                Task t = iTaskServiceImlp.getById(task.getId());
                if (t == null) {
                    return;
                }
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                t.setEndtime(simpleDateFormat.format(new Date()));
                iTaskServiceImlp.updateById(t);
                //解析xml数据 并保存至副表
                List<TaskIp> taskIps = JsoupManger.getMesFromText(command.getOutput().getText(), t.getTasknewid(), task.getSummary());
                //System.out.println(taskIps.size());
                for (int i = 0; i < taskIps.size(); i++) {
                    iTaskIpServiceImlp.save(taskIps.get(i));
                }
                //在检测完资产之后将 信息返回至资产平台
                if (taskIps.size() > 0) {
                    System.out.println("******************" + JSON.toJSONString(taskIps));
                    Thread t1 = new Thread(new Runnable() {
                        public void run() {
                            try {
                                sendMsg(taskIps);
                            } catch (Exception e) {

                            }
                        }
                    });
                    t1.start();
                }
            }
        }
    }


    @Override
    public List<Command> changeCommandnestTOCommand(List<Commandnested> list) {

        List<Command> commands = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {

            commands.add(list.get(i).getCommand());
        }
        return commands;
    }

    //如果一个小时还未有返回结果  则手动返回  失败记录
    @Override
    public void undone() {

        //选择在一个小时以内添加并且未完成的任务，
        DateTime now = new DateTime();
        now = now.plusHours(-2);
        QueryWrapper<Task> queryWrapper = new QueryWrapper();
        queryWrapper.isNull("endtime");
        queryWrapper.apply("UNIX_TIMESTAMP(starttime) < UNIX_TIMESTAMP('" + now + "')");
        List<Task> tasks = taskServiceImpl.list(queryWrapper);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        for (int i = 0; i < tasks.size(); i++) {
            Task task = Task.CloneTask(tasks.get(i));
            task.setEndtime(simpleDateFormat.format(new Date()));
            iTaskServiceImlp.updateById(task);
            //发送消息   并将   当前task的时间参数归置
            TaskIp taskIp = new TaskIp();
            taskIp.setTaskId(tasks.get(i).getTasknewid());
            taskIp.setIp(tasks.get(i).getCode());
            taskIp.setRecordnewid(tasks.get(i).getSummary());
            taskIp.setOs("undone");
            List<TaskIp> taskIps = new ArrayList<>();
            taskIps.add(taskIp);
            Thread t1 = new Thread(new Runnable() {
                public void run() {
                    try {
                        try {
                            sendMsg(taskIps);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    } catch (Exception e) {
                    }
                }
            });
            t1.start();

        }
    }


    public void sendMsg(List<TaskIp> taskIps) throws Exception {

        String url = complexUrl + "/wxmp/assets/getMsg";
        CloseableHttpClient client = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        post.setHeader("Content-Type", "application/json");
        //post.addHeader("Authorization", "Basic YWRtaW46");
        String result;
        try {
            StringEntity s = new StringEntity(JSON.toJSONString(taskIps), "utf-8");
            s.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
                    "application/json"));
            post.setEntity(s);
            // 发送请求
            HttpResponse httpResponse = client.execute(post);
            // 获取响应输入流
            InputStream inStream = httpResponse.getEntity().getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    inStream, "utf-8"));
            StringBuilder strber = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                strber.append(line + "\n");
            }
            inStream.close();
            result = strber.toString();
            if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                System.out.println("请求服务器成功，做相应处理");
            } else {
                System.out.println("请求服务端失败");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
